SlideShare a Scribd company logo
1 of 26
Download to read offline
Parsing Strange:
   URL to SQL to HTML
                          Hal Stern
                 snowmanonfire.com      headshot by Richard Stevens
                                        http://dieselsweeties.com

           slideshare.net/freeholdhal

    © 2010 Hal Stern
Some Rights Reserved
Why Do You Care?
•    Database performance = user experience
•    A little database expertise goes a long way
•    Taxonomies for more than sidebar lists
•    Custom post types
•    WordPress as a powerful CMS >> blog
      > Change default behaviors
      > Defy the common wisdom
      > Integrate other content sources/filters
    © 2010 Hal Stern
Some Rights Reserved               WordCamp NYC 2010   2
Flow of Control
•  Web server URL manipulation
      > Real file or permalink URL?
•  URL to query variables
      > What to display? Tag? Post? Category?
•  Query variables to SQL generation
      > How exactly to get that content?
•  Template file selection
      > How will content be displayed?
•  Content manipulation

    © 2010 Hal Stern
Some Rights Reserved                  WordCamp NYC 2010   3
Whose File Is This?
•  User URL request passed to web server
•  Web server checks
   .htaccess file    <IfModule mod_rewrite.c>
                     RewriteEngine On
                              RewriteBase   /whereyouputWordPress/
      > WP install root       RewriteCond   %{REQUEST_FILENAME} !-f
                              RewriteCond   %{REQUEST_FILENAME} !-d
      > Other .htaccess       RewriteRule
                              </IfModule>
                                            . /index.php [L]

        files may interfere
•  Basic rewriting rules:
   If file or directory URL doesn’t exist, start
   WordPress via index.php
    © 2010 Hal Stern
Some Rights Reserved                  WordCamp NYC 2010               4
Example Meta Fail: 404 Not Found
myblog/
myblog/wp-content (etc)
myblog/images


•  Access broken image URLs for
   unintended results: no 404 pages!
   myblog/images/not-a-pic.jpg!
•  Web server can’t find file, assumes it’s a
   permalink, hands to WP
•  WP can’t interpret it, so defaults to home
    © 2010 Hal Stern
Some Rights Reserved         WordCamp NYC 2010   5
What Happens Before The Loop
•    Parse URL into a query
•    Set conditionals & select templates
•    Execute the query & cache results
•    Run the Loop:
     <?php
     if (have_posts()) :
        while (have_posts()) :
         the_post();
         //loop content
        endwhile;
     endif;
     ?>

    © 2010 Hal Stern
Some Rights Reserved             WordCamp NYC 2010   6
Examining the Query String
<?php
   global $wp_query;
   echo ”SQL for this page ";
   echo $wp_query->request;
   echo "<br>";
?>


•  SQL passed to MySQL in WP_Query
   object’s request element
•  Brute force: edit theme footer.php	
  to
   see main loop’s query for displayed page
    © 2010 Hal Stern
Some Rights Reserved            WordCamp NYC 2010   7
“Home Page” Query Deconstruction

SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts WHERE 1=1
AND wp_posts.post_type = 'post’ AND
(wp_posts.post_status = 'publish' OR
 wp_posts.post_status = 'private’)
ORDER BY wp_posts.post_date DESC LIMIT 0, 10


Get all fields from posts table, but limit number of returned rows

Only get posts, and those that are published or private to the user

Sort the results by date in descending order

Start results starting with record 0 and up to 10 more results



    © 2010 Hal Stern
Some Rights Reserved                               WordCamp NYC 2010   8
Query Parsing
•  parse_request() method of WP_Query
   extracts query variables from URL
•  Execute rewrite rules
      > Pick off ?p=67 style http GET variables
      > Match permalink structure
      > Match keywords like “author” and “tag”
      > Match custom post type slugs


    © 2010 Hal Stern
Some Rights Reserved              WordCamp NYC 2010   9
Query Variables to SQL
•  Query type: post by title, posts by category
   or tag, posts by date
•  Variables for the query
      > Slug values for category/tags
      > Month/day numbers
      > Explicit variable values
•  post_type variable has been around for
   a while; CPT queries fill in new values
    © 2010 Hal Stern
Some Rights Reserved              WordCamp NYC 2010   10
Simple Title Slug Parsing
/2010/premio-sausage




     SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND YEAR
     (wp_posts.post_date)='2010' AND wp_posts.post_name = 'premio-
     sausage' AND wp_posts.post_type = 'post' ORDER BY
     wp_posts.post_date DESC

•  Rewrite matches root of permalink,
   extracts tail of URL as a title slug

    © 2010 Hal Stern
Some Rights Reserved                      WordCamp NYC 2010          11
CPT Query Variables
•  Register CPT with a custom query variable
      'query_var' => 'ebay'
•  Variable works in URLs like built-ins
      myblog.com/?ebay=current_items
      myblog.com/?ebay=cool_searches
•  Variable value matches CPT title slug



    © 2010 Hal Stern
Some Rights Reserved          WordCamp NYC 2010   12
WordPress Meta Data
•  Common DB mechanics for all meta data
      > Categories, tags, custom taxonomies
•  Normalized down to 3 tables
      > Terms: word strings and their slugs
      > Taxonomies: collections of terms
      > Relationships: terms attached to posts
•  It’s so simple it gets really complex.
   Really.
    © 2010 Hal Stern
Some Rights Reserved              WordCamp NYC 2010   13
Graphs and JOIN Operations
•  WordPress maps tags and categories 1:N
   to posts (each term in many posts)
•  You need to punch MySQL to handle this
      > INNER JOIN builds intermediate tables on
        common key values
•  Following link in a graph is equivalent to
   an INNER JOIN on tables of linked items


    © 2010 Hal Stern
Some Rights Reserved             WordCamp NYC 2010   14
WordPress Taxonomy Tables

wp_posts               wp_term_relationships       wp_term_taxonomy
post_id                object_id                   term_taxonomy_id
….                     term_taxonomy_id            term_id
post_date                                          taxonomy
…                                                  description
post_content


•  Term relationships table maps
   N terms to each post                            wp_terms
                                                   term_id
•  Term taxonomy maps N                            name
   terms to each taxonomy                          slug
•  Term table has slugs for URL
   mapping
    © 2010 Hal Stern
Some Rights Reserved                           WordCamp NYC 2010      15
Taxonomy Lookup
  /tag/premio




SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts
INNER JOIN wp_term_relationships ON
(wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_term_taxonomy ON
  (wp_term_relationships.term_taxonomy_id =
   wp_term_taxonomy.term_taxonomy_id)
INNER JOIN wp_terms ON
   (wp_term_taxonomy.term_id = wp_terms.term_id)
WHERE 1=1 AND wp_term_taxonomy.taxonomy = 'post_tag' AND wp_terms.slug IN
('premio') AND wp_posts.post_type = 'post' AND (wp_posts.post_status =
'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER
BY wp_posts.post_date DESC LIMIT 0, 10

    © 2010 Hal Stern
Some Rights Reserved                          WordCamp NYC 2010             16
More on Canonical URLs
•  Canonical URLs improve SEO
•  WordPress is really good about generating
   301 Redirects for non-standard URLs
•  Example: URL doesn’t appear to match a
   permalink, WordPress does prediction
      > Use “LIKE title%” in WHERE clause
      > Matches “title” as initial substring with %
        wildcard

    © 2010 Hal Stern
Some Rights Reserved               WordCamp NYC 2010   17
Modifying the Query
•  Brute force isn’t necessarily good
      > Using query_posts() ignores all previous
        parsing, runs a new SQL query
•  Filter query_vars
      > Change default parsing (convert any day to a
        week’s worth of posts, for example)
•  Actions parse_query & parse_request
      > Access WP_Query object before execution
      > is_xx() conditionals are already set

    © 2010 Hal Stern
Some Rights Reserved              WordCamp NYC 2010   18
SQL Generation Filters
•  posts_where
      > More explicit control over query variable to
        SQL grammar mapping
•  posts_join
      > Add or modify JOIN operations for other graph
        relationships
•  Many other filters
      > Change grouping of results
      > Change ordering of results

    © 2010 Hal Stern
Some Rights Reserved               WordCamp NYC 2010   19
Custom Post Types
•  Change SQL WHERE clause on post type
      > wp_posts.post_type=‘ebay’
•  Add new rewrite rules for URL parsing similar
   to category & tag
      > Set slug in CPT registration array
           'rewrite' => array ("slug" => “ebay”),
•  Watch out for competing, overwritten or
   unflushed rewrite entries
    <?php echo "<pre>”;
    print_r(get_option('rewrite_rules'));
    echo "</pre>”;
    ?>
    © 2010 Hal Stern
Some Rights Reserved                 WordCamp NYC 2010   20
Applications
•  Stylized listings
      > Category sorted alphabetically
      > Use posts as listings of resources (jobs,
        clients, events) – good CPT application
•  Custom URL slugs
      > Add rewrite rules to match slug and set query
        variables
•  Joining other social graphs
      > Suggested/related content

    © 2010 Hal Stern
Some Rights Reserved                WordCamp NYC 2010   21
Template File Selection
•  is_x() conditionals set in query parsing
•  Used to drive template selection
      > is_tag() looks for tag-slug, tag-id, then tag
      > Full search hierarchy in Codex
•  template_redirect action
      > Called in the template loader
      > Add actions to override defaults


    © 2010 Hal Stern
Some Rights Reserved               WordCamp NYC 2010   22
HTML Generation
•  Done in the_post() method
•  Raw content retrieved from MySQL
      > Short codes interpreted
      > CSS applied
•  Some caching plugins generate and store
   HTML, so YMMV



    © 2010 Hal Stern
Some Rights Reserved              WordCamp NYC 2010   23
Why Do You Care?
•  User experience improvement
      > JOINS are expensive
      > Large post table & repetitive SELECTs = slow
      > Running query once keeps cache warm
      > Category, permalink, title slug choices matter
•  More CMS, less “blog”
      > Alphabetical sort
      > Adding taxonomy/social graph elements

    © 2010 Hal Stern
Some Rights Reserved              WordCamp NYC 2010   24
Resources

•  Core files where SQL stuff happens
      > query.php
      > post.php
      > canonical.php
      > rewrite.php
•  Template	
  loader	
  search	
  path	
  
      >  http://codex.wordpress.org/Template_Hierarchy



    © 2010 Hal Stern
Some Rights Reserved                     WordCamp NYC 2010   25
Contact
Hal Stern
freeholdhal@gmail.com
@freeholdhal
snowmanonfire.com
facebook.com/hal.stern

Other Projects:
amphibimen.com
facebook.com/letusin

slideshare.net/freeholdhal


    © 2010 Hal Stern
Some Rights Reserved         WordCamp NYC 2010   26

More Related Content

What's hot

Tutorial on developing a Solr search component plugin
Tutorial on developing a Solr search component pluginTutorial on developing a Solr search component plugin
Tutorial on developing a Solr search component pluginsearchbox-com
 
Solr Recipes Workshop
Solr Recipes WorkshopSolr Recipes Workshop
Solr Recipes WorkshopErik Hatcher
 
Using Apache Solr
Using Apache SolrUsing Apache Solr
Using Apache Solrpittaya
 
Solr 6 Feature Preview
Solr 6 Feature PreviewSolr 6 Feature Preview
Solr 6 Feature PreviewYonik Seeley
 
Dynamic Publishing with Arbortext Data Merge
Dynamic Publishing with Arbortext Data MergeDynamic Publishing with Arbortext Data Merge
Dynamic Publishing with Arbortext Data MergeClay Helberg
 
Advancing Your Custom Fields - WordCamp 2014
Advancing Your Custom Fields - WordCamp 2014Advancing Your Custom Fields - WordCamp 2014
Advancing Your Custom Fields - WordCamp 2014Carleton Web Services
 
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami
 
Rebuilding Solr 6 examples - layer by layer (LuceneSolrRevolution 2016)
Rebuilding Solr 6 examples - layer by layer (LuceneSolrRevolution 2016)Rebuilding Solr 6 examples - layer by layer (LuceneSolrRevolution 2016)
Rebuilding Solr 6 examples - layer by layer (LuceneSolrRevolution 2016)Alexandre Rafalovitch
 
Using Neo4j from Java
Using Neo4j from JavaUsing Neo4j from Java
Using Neo4j from JavaNeo4j
 
Get the most out of Solr search with PHP
Get the most out of Solr search with PHPGet the most out of Solr search with PHP
Get the most out of Solr search with PHPPaul Borgermans
 
Solr Black Belt Pre-conference
Solr Black Belt Pre-conferenceSolr Black Belt Pre-conference
Solr Black Belt Pre-conferenceErik Hatcher
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with SolrErik Hatcher
 
An Introduction to Basics of Search and Relevancy with Apache Solr
An Introduction to Basics of Search and Relevancy with Apache SolrAn Introduction to Basics of Search and Relevancy with Apache Solr
An Introduction to Basics of Search and Relevancy with Apache SolrLucidworks (Archived)
 
Deepak khetawat sling_models_sightly_jsp
Deepak khetawat sling_models_sightly_jspDeepak khetawat sling_models_sightly_jsp
Deepak khetawat sling_models_sightly_jspDEEPAK KHETAWAT
 
Introduction to Solr
Introduction to SolrIntroduction to Solr
Introduction to SolrErik Hatcher
 

What's hot (20)

Tutorial on developing a Solr search component plugin
Tutorial on developing a Solr search component pluginTutorial on developing a Solr search component plugin
Tutorial on developing a Solr search component plugin
 
Solr Recipes Workshop
Solr Recipes WorkshopSolr Recipes Workshop
Solr Recipes Workshop
 
Using Apache Solr
Using Apache SolrUsing Apache Solr
Using Apache Solr
 
Kick start @ html5
Kick start @ html5Kick start @ html5
Kick start @ html5
 
Apache Solr
Apache SolrApache Solr
Apache Solr
 
Solr 6 Feature Preview
Solr 6 Feature PreviewSolr 6 Feature Preview
Solr 6 Feature Preview
 
Dynamic Publishing with Arbortext Data Merge
Dynamic Publishing with Arbortext Data MergeDynamic Publishing with Arbortext Data Merge
Dynamic Publishing with Arbortext Data Merge
 
Advancing Your Custom Fields - WordCamp 2014
Advancing Your Custom Fields - WordCamp 2014Advancing Your Custom Fields - WordCamp 2014
Advancing Your Custom Fields - WordCamp 2014
 
Apache Solr Workshop
Apache Solr WorkshopApache Solr Workshop
Apache Solr Workshop
 
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
dotNet Miami - June 21, 2012: Richie Rump: Entity Framework: Code First and M...
 
Rebuilding Solr 6 examples - layer by layer (LuceneSolrRevolution 2016)
Rebuilding Solr 6 examples - layer by layer (LuceneSolrRevolution 2016)Rebuilding Solr 6 examples - layer by layer (LuceneSolrRevolution 2016)
Rebuilding Solr 6 examples - layer by layer (LuceneSolrRevolution 2016)
 
Using Neo4j from Java
Using Neo4j from JavaUsing Neo4j from Java
Using Neo4j from Java
 
Get the most out of Solr search with PHP
Get the most out of Solr search with PHPGet the most out of Solr search with PHP
Get the most out of Solr search with PHP
 
Solr Black Belt Pre-conference
Solr Black Belt Pre-conferenceSolr Black Belt Pre-conference
Solr Black Belt Pre-conference
 
Content Modeling Behavior
Content Modeling BehaviorContent Modeling Behavior
Content Modeling Behavior
 
Introduction to Apache Solr
Introduction to Apache SolrIntroduction to Apache Solr
Introduction to Apache Solr
 
Rapid Prototyping with Solr
Rapid Prototyping with SolrRapid Prototyping with Solr
Rapid Prototyping with Solr
 
An Introduction to Basics of Search and Relevancy with Apache Solr
An Introduction to Basics of Search and Relevancy with Apache SolrAn Introduction to Basics of Search and Relevancy with Apache Solr
An Introduction to Basics of Search and Relevancy with Apache Solr
 
Deepak khetawat sling_models_sightly_jsp
Deepak khetawat sling_models_sightly_jspDeepak khetawat sling_models_sightly_jsp
Deepak khetawat sling_models_sightly_jsp
 
Introduction to Solr
Introduction to SolrIntroduction to Solr
Introduction to Solr
 

Similar to Parsing strange v3

Parsing strange v1.1
Parsing strange v1.1Parsing strange v1.1
Parsing strange v1.1Hal Stern
 
Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019Adam Tomat
 
The WordPress University 2012
The WordPress University 2012The WordPress University 2012
The WordPress University 2012Stephanie Leary
 
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...Lucidworks
 
Best Practices for WordPress
Best Practices for WordPressBest Practices for WordPress
Best Practices for WordPressTaylor Lovett
 
Wordpress theme development
Wordpress theme developmentWordpress theme development
Wordpress theme developmentNaeem Junejo
 
PHP and MySQL.pptx
PHP and MySQL.pptxPHP and MySQL.pptx
PHP and MySQL.pptxnatesanp1234
 
Learning to run
Learning to runLearning to run
Learning to rundominion
 
Web Services PHP Tutorial
Web Services PHP TutorialWeb Services PHP Tutorial
Web Services PHP TutorialLorna Mitchell
 
Houston tech fest dev intro to sharepoint search
Houston tech fest   dev intro to sharepoint searchHouston tech fest   dev intro to sharepoint search
Houston tech fest dev intro to sharepoint searchMichael Oryszak
 
Customizing the SharePoint 2013 user interface with JavaScript - Chris OBrien
Customizing the SharePoint 2013 user interface with JavaScript - Chris OBrienCustomizing the SharePoint 2013 user interface with JavaScript - Chris OBrien
Customizing the SharePoint 2013 user interface with JavaScript - Chris OBrienChris O'Brien
 
SFDC Inbound Integrations
SFDC Inbound IntegrationsSFDC Inbound Integrations
SFDC Inbound IntegrationsSujit Kumar
 
[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress DevelopmentAdam Tomat
 
Essentials for the SharePoint Power User - SharePoint Engage Raleigh 2017
Essentials for the SharePoint Power User - SharePoint Engage Raleigh 2017Essentials for the SharePoint Power User - SharePoint Engage Raleigh 2017
Essentials for the SharePoint Power User - SharePoint Engage Raleigh 2017Drew Madelung
 
Modeling Tricks My Relational Database Never Taught Me
Modeling Tricks My Relational Database Never Taught MeModeling Tricks My Relational Database Never Taught Me
Modeling Tricks My Relational Database Never Taught MeDavid Boike
 
Intro to .NET for Government Developers
Intro to .NET for Government DevelopersIntro to .NET for Government Developers
Intro to .NET for Government DevelopersFrank La Vigne
 
Carrington Core (2014)
Carrington Core (2014)Carrington Core (2014)
Carrington Core (2014)alexkingorg
 

Similar to Parsing strange v3 (20)

Parsing strange v1.1
Parsing strange v1.1Parsing strange v1.1
Parsing strange v1.1
 
&lt;?php + WordPress
&lt;?php + WordPress&lt;?php + WordPress
&lt;?php + WordPress
 
Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019Supercharging WordPress Development - Wordcamp Brighton 2019
Supercharging WordPress Development - Wordcamp Brighton 2019
 
The WordPress University 2012
The WordPress University 2012The WordPress University 2012
The WordPress University 2012
 
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
Challenges of Simple Documents: When Basic isn't so Basic - Cassandra Targett...
 
Best Practices for WordPress
Best Practices for WordPressBest Practices for WordPress
Best Practices for WordPress
 
Wordpress theme development
Wordpress theme developmentWordpress theme development
Wordpress theme development
 
PHP and MySQL.pptx
PHP and MySQL.pptxPHP and MySQL.pptx
PHP and MySQL.pptx
 
Learning to run
Learning to runLearning to run
Learning to run
 
Web Services PHP Tutorial
Web Services PHP TutorialWeb Services PHP Tutorial
Web Services PHP Tutorial
 
Houston tech fest dev intro to sharepoint search
Houston tech fest   dev intro to sharepoint searchHouston tech fest   dev intro to sharepoint search
Houston tech fest dev intro to sharepoint search
 
Customizing the SharePoint 2013 user interface with JavaScript - Chris OBrien
Customizing the SharePoint 2013 user interface with JavaScript - Chris OBrienCustomizing the SharePoint 2013 user interface with JavaScript - Chris OBrien
Customizing the SharePoint 2013 user interface with JavaScript - Chris OBrien
 
Practical OData
Practical ODataPractical OData
Practical OData
 
SFDC Inbound Integrations
SFDC Inbound IntegrationsSFDC Inbound Integrations
SFDC Inbound Integrations
 
[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development[Bristol WordPress] Supercharging WordPress Development
[Bristol WordPress] Supercharging WordPress Development
 
Essentials for the SharePoint Power User - SharePoint Engage Raleigh 2017
Essentials for the SharePoint Power User - SharePoint Engage Raleigh 2017Essentials for the SharePoint Power User - SharePoint Engage Raleigh 2017
Essentials for the SharePoint Power User - SharePoint Engage Raleigh 2017
 
Modeling Tricks My Relational Database Never Taught Me
Modeling Tricks My Relational Database Never Taught MeModeling Tricks My Relational Database Never Taught Me
Modeling Tricks My Relational Database Never Taught Me
 
Intro to .NET for Government Developers
Intro to .NET for Government DevelopersIntro to .NET for Government Developers
Intro to .NET for Government Developers
 
Life outside WO
Life outside WOLife outside WO
Life outside WO
 
Carrington Core (2014)
Carrington Core (2014)Carrington Core (2014)
Carrington Core (2014)
 

Parsing strange v3

  • 1. Parsing Strange: URL to SQL to HTML Hal Stern snowmanonfire.com headshot by Richard Stevens http://dieselsweeties.com slideshare.net/freeholdhal © 2010 Hal Stern Some Rights Reserved
  • 2. Why Do You Care? •  Database performance = user experience •  A little database expertise goes a long way •  Taxonomies for more than sidebar lists •  Custom post types •  WordPress as a powerful CMS >> blog > Change default behaviors > Defy the common wisdom > Integrate other content sources/filters © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 2
  • 3. Flow of Control •  Web server URL manipulation > Real file or permalink URL? •  URL to query variables > What to display? Tag? Post? Category? •  Query variables to SQL generation > How exactly to get that content? •  Template file selection > How will content be displayed? •  Content manipulation © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 3
  • 4. Whose File Is This? •  User URL request passed to web server •  Web server checks .htaccess file <IfModule mod_rewrite.c> RewriteEngine On RewriteBase /whereyouputWordPress/ > WP install root RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d > Other .htaccess RewriteRule </IfModule> . /index.php [L] files may interfere •  Basic rewriting rules: If file or directory URL doesn’t exist, start WordPress via index.php © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 4
  • 5. Example Meta Fail: 404 Not Found myblog/ myblog/wp-content (etc) myblog/images •  Access broken image URLs for unintended results: no 404 pages! myblog/images/not-a-pic.jpg! •  Web server can’t find file, assumes it’s a permalink, hands to WP •  WP can’t interpret it, so defaults to home © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 5
  • 6. What Happens Before The Loop •  Parse URL into a query •  Set conditionals & select templates •  Execute the query & cache results •  Run the Loop: <?php if (have_posts()) : while (have_posts()) : the_post(); //loop content endwhile; endif; ?> © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 6
  • 7. Examining the Query String <?php global $wp_query; echo ”SQL for this page "; echo $wp_query->request; echo "<br>"; ?> •  SQL passed to MySQL in WP_Query object’s request element •  Brute force: edit theme footer.php  to see main loop’s query for displayed page © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 7
  • 8. “Home Page” Query Deconstruction SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post’ AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private’) ORDER BY wp_posts.post_date DESC LIMIT 0, 10 Get all fields from posts table, but limit number of returned rows Only get posts, and those that are published or private to the user Sort the results by date in descending order Start results starting with record 0 and up to 10 more results © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 8
  • 9. Query Parsing •  parse_request() method of WP_Query extracts query variables from URL •  Execute rewrite rules > Pick off ?p=67 style http GET variables > Match permalink structure > Match keywords like “author” and “tag” > Match custom post type slugs © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 9
  • 10. Query Variables to SQL •  Query type: post by title, posts by category or tag, posts by date •  Variables for the query > Slug values for category/tags > Month/day numbers > Explicit variable values •  post_type variable has been around for a while; CPT queries fill in new values © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 10
  • 11. Simple Title Slug Parsing /2010/premio-sausage SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND YEAR (wp_posts.post_date)='2010' AND wp_posts.post_name = 'premio- sausage' AND wp_posts.post_type = 'post' ORDER BY wp_posts.post_date DESC •  Rewrite matches root of permalink, extracts tail of URL as a title slug © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 11
  • 12. CPT Query Variables •  Register CPT with a custom query variable 'query_var' => 'ebay' •  Variable works in URLs like built-ins myblog.com/?ebay=current_items myblog.com/?ebay=cool_searches •  Variable value matches CPT title slug © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 12
  • 13. WordPress Meta Data •  Common DB mechanics for all meta data > Categories, tags, custom taxonomies •  Normalized down to 3 tables > Terms: word strings and their slugs > Taxonomies: collections of terms > Relationships: terms attached to posts •  It’s so simple it gets really complex. Really. © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 13
  • 14. Graphs and JOIN Operations •  WordPress maps tags and categories 1:N to posts (each term in many posts) •  You need to punch MySQL to handle this > INNER JOIN builds intermediate tables on common key values •  Following link in a graph is equivalent to an INNER JOIN on tables of linked items © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 14
  • 15. WordPress Taxonomy Tables wp_posts wp_term_relationships wp_term_taxonomy post_id object_id term_taxonomy_id …. term_taxonomy_id term_id post_date taxonomy … description post_content •  Term relationships table maps N terms to each post wp_terms term_id •  Term taxonomy maps N name terms to each taxonomy slug •  Term table has slugs for URL mapping © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 15
  • 16. Taxonomy Lookup /tag/premio SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id) INNER JOIN wp_terms ON (wp_term_taxonomy.term_id = wp_terms.term_id) WHERE 1=1 AND wp_term_taxonomy.taxonomy = 'post_tag' AND wp_terms.slug IN ('premio') AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10 © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 16
  • 17. More on Canonical URLs •  Canonical URLs improve SEO •  WordPress is really good about generating 301 Redirects for non-standard URLs •  Example: URL doesn’t appear to match a permalink, WordPress does prediction > Use “LIKE title%” in WHERE clause > Matches “title” as initial substring with % wildcard © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 17
  • 18. Modifying the Query •  Brute force isn’t necessarily good > Using query_posts() ignores all previous parsing, runs a new SQL query •  Filter query_vars > Change default parsing (convert any day to a week’s worth of posts, for example) •  Actions parse_query & parse_request > Access WP_Query object before execution > is_xx() conditionals are already set © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 18
  • 19. SQL Generation Filters •  posts_where > More explicit control over query variable to SQL grammar mapping •  posts_join > Add or modify JOIN operations for other graph relationships •  Many other filters > Change grouping of results > Change ordering of results © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 19
  • 20. Custom Post Types •  Change SQL WHERE clause on post type > wp_posts.post_type=‘ebay’ •  Add new rewrite rules for URL parsing similar to category & tag > Set slug in CPT registration array 'rewrite' => array ("slug" => “ebay”), •  Watch out for competing, overwritten or unflushed rewrite entries <?php echo "<pre>”; print_r(get_option('rewrite_rules')); echo "</pre>”; ?> © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 20
  • 21. Applications •  Stylized listings > Category sorted alphabetically > Use posts as listings of resources (jobs, clients, events) – good CPT application •  Custom URL slugs > Add rewrite rules to match slug and set query variables •  Joining other social graphs > Suggested/related content © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 21
  • 22. Template File Selection •  is_x() conditionals set in query parsing •  Used to drive template selection > is_tag() looks for tag-slug, tag-id, then tag > Full search hierarchy in Codex •  template_redirect action > Called in the template loader > Add actions to override defaults © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 22
  • 23. HTML Generation •  Done in the_post() method •  Raw content retrieved from MySQL > Short codes interpreted > CSS applied •  Some caching plugins generate and store HTML, so YMMV © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 23
  • 24. Why Do You Care? •  User experience improvement > JOINS are expensive > Large post table & repetitive SELECTs = slow > Running query once keeps cache warm > Category, permalink, title slug choices matter •  More CMS, less “blog” > Alphabetical sort > Adding taxonomy/social graph elements © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 24
  • 25. Resources •  Core files where SQL stuff happens > query.php > post.php > canonical.php > rewrite.php •  Template  loader  search  path   >  http://codex.wordpress.org/Template_Hierarchy © 2010 Hal Stern Some Rights Reserved WordCamp NYC 2010 25